﻿using Abp.Dependency;
using Abp.Domain.Uow;
using Abp.Runtime.Session;
using Hicap.AuthorizationServer.Core.Models;
using Hicap.AuthorizationServer.Core.Notify;
using Newtonsoft.Json;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using IUnitOfWork = Hicap.AuthorizationServer.Core.Common.EFCore.IUnitOfWork;

namespace Hicap.AuthorizationServer.Core.Managers
{
    public class NotificationManager : ManagerBase<Notification>, INotificationManager
    {
        public NotificationManager(IUnitOfWork unitOfWork, IAbpSession session) : base(unitOfWork)
        {
            QueryCondition.Add(x => x.IsDeleted == false);
            CreateActions.Add(x => x.CreatorUserId = session.UserId);
            CreateActions.Add(x => x.CreationTime = DateTime.Now);
            UpdateActions.Add(x => x.LastModificationTime = DateTime.Now);
            UpdateActions.Add(x => x.LastModifierUserId = session.UserId);
            DeleteActions.Add(x => x.DeletionTime = DateTime.Now);
            DeleteActions.Add(x => x.DeleterUserId = session.UserId);
            DeleteActions.Add(x => x.IsDeleted = true);

            CreateCheckActions.Add(x =>
            {
                if (x.Id == 0) return true;
                Log.Warning($"Notification CreateCheck Fail : {JsonConvert.SerializeObject(x)}");
                return false;
            });
            UpdateCheckActions.Add(x =>
            {
                if (x.Id > 0 && x.IsDeleted == false) return true;
                Log.Warning($"Notification UpdateCheck Fail : {JsonConvert.SerializeObject(x)}");
                return false;
            });
            DeleteCheckActions.Add(x =>
            {
                if (x.IsDeleted == false) return true;
                Log.Warning($"Notification DeleteCheck Fail : {JsonConvert.SerializeObject(x)}");
                return false;
            });
        }

        [UnitOfWork]
        public void FinishedMessage(List<int> idList)
        {
            idList.ForEach(async x => await Delete(x)
            );
        }

        [UnitOfWork]
        public Task<List<string>> ReadMessage(string type)
        {
            return Task.Run(() =>
            {
                return GetQuery(x => x.Type.Equals(type))
                    .Select(x => $"[{x.Id}]{x.MessageContent}").ToList();
            });
        }

        [UnitOfWork]
        public async Task Echo(string type, string message)
        {
            Notification entity = new Models.Notification()
            {
                @Type = type,
                MessageContent = message
            };

            int messageId = await InsertAndGetId(entity);
            await SendNotification(type, message, messageId);
        }

        private async Task SendNotification(string type, string message, int messageId)
        {
            NotifyHub hub = IocManager.Instance.Resolve<NotifyHub>();
            hub.Type = type;
            await hub.SendToGroup($"[{messageId}]{message}");
        }
    }
}